package com.geo.ai.controller;

import com.geo.ai.adapter.AIModelAdapter;
import com.geo.ai.adapter.ModelUsageStats;
import com.geo.ai.model.AIRequest;
import com.geo.ai.model.AIResponse;
import com.geo.ai.service.AIModelManager;
import com.geo.common.result.Result;
import com.geo.common.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;

/**
 * AI模型管理API控制器
 * 
 * @author GEO Team
 * @version 1.0
 */
@Slf4j
@RestController
@RequestMapping("/api/ai")
@Validated
public class AIModelController {
    
    private static final Logger log = LoggerFactory.getLogger(AIModelController.class);
    
    @Autowired
    private AIModelManager aiModelManager;
    
    /**
     * 调用AI模型
     * @param request AI请求
     * @return AI响应
     */
    @PostMapping("/invoke")
    public Result<AIResponse> invokeAI(@Valid @RequestBody AIRequest request) {
        try {
            AIResponse response = aiModelManager.invoke(request);
            
            log.info("AI模型调用成功: {} - {}", request.getTaskType(), response.getModelName());
            return Result.success(response);
            
        } catch (Exception e) {
            log.error("AI模型调用失败", e);
            return Result.error(ResultCode.AI_API_ERROR, e.getMessage());
        }
    }
    
    /**
     * 使用指定模型调用AI
     * @param modelName 模型名称
     * @param request AI请求
     * @return AI响应
     */
    @PostMapping("/invoke/{modelName}")
    public Result<AIResponse> invokeSpecificModel(@PathVariable String modelName,
                                                 @Valid @RequestBody AIRequest request) {
        try {
            AIResponse response = aiModelManager.invokeWithSpecificModel(request, modelName);
            
            log.info("指定AI模型调用成功: {} - {}", modelName, request.getTaskType());
            return Result.success(response);
            
        } catch (Exception e) {
            log.error("指定AI模型调用失败: {}", modelName, e);
            return Result.error(ResultCode.AI_MODEL_NOT_FOUND, e.getMessage());
        }
    }
    
    /**
     * 获取可用的AI模型列表
     * @return 模型列表
     */
    @GetMapping("/models")
    public Result<List<ModelInfo>> getAvailableModels() {
        try {
            List<AIModelAdapter> adapters = aiModelManager.getAvailableModels();
            
            List<ModelInfo> modelInfos = adapters.stream()
                    .map(adapter -> ModelInfo.builder()
                            .adapterName(adapter.getAdapterName())
                            .modelType(adapter.getModelType())
                            .modelName(adapter.getModelConfig().getModelName())
                            .provider(adapter.getModelConfig().getProvider())
                            .priority(adapter.getModelConfig().getPriority())
                            .enabled(adapter.getModelConfig().getEnabled())
                            .capabilities(adapter.getModelConfig().getCapabilities())
                            .build())
                    .toList();
            
            return Result.success(modelInfos);
            
        } catch (Exception e) {
            log.error("获取AI模型列表失败", e);
            return Result.error(ResultCode.FAILURE, e.getMessage());
        }
    }
    
    /**
     * 获取AI模型使用统计
     * @return 使用统计
     */
    @GetMapping("/usage-stats")
    public Result<Map<String, ModelUsageStats>> getUsageStats() {
        try {
            Map<String, ModelUsageStats> stats = aiModelManager.getUsageStats();
            return Result.success(stats);
            
        } catch (Exception e) {
            log.error("获取AI模型使用统计失败", e);
            return Result.error(ResultCode.FAILURE, e.getMessage());
        }
    }
    
    /**
     * 重置所有模型的使用统计
     * @return 重置结果
     */
    @PostMapping("/reset-stats")
    public Result<String> resetUsageStats() {
        try {
            aiModelManager.resetAllUsageStats();
            
            log.info("AI模型使用统计已重置");
            return Result.success("使用统计重置成功");
            
        } catch (Exception e) {
            log.error("重置AI模型使用统计失败", e);
            return Result.error(ResultCode.FAILURE, e.getMessage());
        }
    }
    
    /**
     * AI模型健康检查
     * @return 健康状态
     */
    @GetMapping("/health")
    public Result<Map<String, Boolean>> healthCheck() {
        try {
            Map<String, Boolean> healthStatus = aiModelManager.healthCheck();
            return Result.success(healthStatus);
            
        } catch (Exception e) {
            log.error("AI模型健康检查失败", e);
            return Result.error(ResultCode.FAILURE, e.getMessage());
        }
    }
    
    /**
     * 测试AI模型连接
     * @param modelName 模型名称
     * @return 测试结果
     */
    @PostMapping("/test/{modelName}")
    public Result<String> testModel(@PathVariable String modelName) {
        try {
            AIRequest testRequest = AIRequest.builder()
                    .taskType(AIRequest.TaskType.CONTENT_GENERATION)
                    .userInput("测试连接")
                    .maxTokens(10)
                    .temperature(0.1)
                    .build();
            
            AIResponse response = aiModelManager.invokeWithSpecificModel(testRequest, modelName);
            
            if (response.isSuccess()) {
                return Result.success("模型连接测试成功");
            } else {
                return Result.error(ResultCode.AI_MODEL_UNAVAILABLE, "模型连接测试失败: " + response.getErrorMessage());
            }
            
        } catch (Exception e) {
            log.error("AI模型连接测试失败: {}", modelName, e);
            return Result.error(ResultCode.AI_MODEL_UNAVAILABLE, e.getMessage());
        }
    }
    
    /**
     * 模型信息DTO
     */
    @lombok.Data
    @lombok.Builder
    @lombok.AllArgsConstructor
    @lombok.NoArgsConstructor
    public static class ModelInfo {
        private String adapterName;
        private String modelType;
        private String modelName;
        private String provider;
        private Integer priority;
        private Boolean enabled;
        private Object capabilities;
        
        // 手动添加builder方法以解决编译问题
        public static ModelInfoBuilder builder() {
            return new ModelInfoBuilder();
        }
        
        public static class ModelInfoBuilder {
            private String adapterName;
            private String modelType;
            private String modelName;
            private String provider;
            private Integer priority;
            private Boolean enabled;
            private Object capabilities;
            
            public ModelInfoBuilder adapterName(String adapterName) {
                this.adapterName = adapterName;
                return this;
            }
            
            public ModelInfoBuilder modelType(String modelType) {
                this.modelType = modelType;
                return this;
            }
            
            public ModelInfoBuilder modelName(String modelName) {
                this.modelName = modelName;
                return this;
            }
            
            public ModelInfoBuilder provider(String provider) {
                this.provider = provider;
                return this;
            }
            
            public ModelInfoBuilder priority(Integer priority) {
                this.priority = priority;
                return this;
            }
            
            public ModelInfoBuilder enabled(Boolean enabled) {
                this.enabled = enabled;
                return this;
            }
            
            public ModelInfoBuilder capabilities(Object capabilities) {
                this.capabilities = capabilities;
                return this;
            }
            
            public ModelInfo build() {
                ModelInfo modelInfo = new ModelInfo();
                modelInfo.adapterName = this.adapterName;
                modelInfo.modelType = this.modelType;
                modelInfo.modelName = this.modelName;
                modelInfo.provider = this.provider;
                modelInfo.priority = this.priority;
                modelInfo.enabled = this.enabled;
                modelInfo.capabilities = this.capabilities;
                return modelInfo;
            }
        }
    }
}